﻿using PBO.Data;
using PBO.Data.PokemonOnline;
using PBO.Data.Rnd;
using PBO.Data.SQLite;
using PBO.Data.SQLite.DAL;
using PBO.Data.Util;
using PBO.Game.BattleClass;
using PBO.Game.Img;
using PBO.Properties;
using PBO.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Top.Api;

namespace PBO.Forms.DataForm
{
    public partial class TeamEditorForm : Form
    {

        public TeamEditorForm()
        {
            InitializeComponent();
            this.Icon = Properties.Resources.PokemonBall;
            this.cmdBox.Text = "复制";
            //scTeam.Panel2Collapsed = true;
            GetMoveText().ToList().ForEach(t => t.GotFocus += txtMoves_GotFocus);
            UpdateData();
            MoveSorter = new ListSorter();
            MoveList.ListViewItemSorter = MoveSorter;
            MoveList.SmallImageList = ImageHelper.GetTypeList();
            var team = MainForm.GetInstance().Team;

            if (team == null)
            {
                team = RandomData.GetSmogonTeam(new Random());
            }

            if (team == null)
            {
                NewTeam();
            }
            else
            {
                OpenTeam(team, true);
            }
        }

        #region Instance

        private static TeamEditorForm instance;

        public static TeamEditorForm GetInstance()
        {
            if (instance == null || instance.IsDisposed)
                instance = new TeamEditorForm();
            instance.MdiParent = MainForm.GetInstance();
            return instance;
        }

        private MainForm MotherForm
        {
            get { return MainForm.GetInstance(); }
        }

        #endregion

        #region bind

        public void UpdateData()
        {
            PokemonCombo.Items.Clear();
            BindName();
            PokemonList.SelectedIndices.Clear();
            BindTeam(this.Team);
            ClearText();
        }

        private void BindName()
        {
            PokemonCombo.DataSource = DALPokemonData.GetAllNames();
            PokemonCombo.DisplayMember = "name";
            PokemonCombo.ValueMember = "pmid";

            ItemCombo.DataSource = SQLiteHelper.Item.GetAllName();
            ItemCombo.DisplayMember = "name";
            ItemCombo.ValueMember = "itemid";
        }

        #endregion

        #region old

        private TeamData Team;
        private TeamData tempTeam;
        private PokemonCustomInfo CurrentInfo = PokemonCustomInfo.EmptyPokemon;

        private ListSorter MoveSorter;
        private bool updating;
        private bool lstUpdating;

        private void FrmTeamEditor_Load(object sender, System.EventArgs e)
        {
            ExpertButton.Enabled = false;
            ItemCombo.Enabled = false;
            LVNumberic.Enabled = false;
            NickNameText.Enabled = false;
            //GetBox();
            //HideBox();
        }

        private void TeamEditorForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason != CloseReason.MdiFormClosing)
            {
                e.Cancel = true;
            }
            if (Team.Pokemons[0].Identity == 0)
            {
                MessageBox.Show("至少选择1只宝可梦！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var pm = Team.Pokemons.FirstOrDefault(p => p.Identity != 0 && p.Moves[0] == 0);

            if (pm != null)
            {
                MessageBox.Show(pm.NickName + "没有技能！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!CloseTeam()) return;
            //SaveBox();
            PokemonList.SelectedIndices.Clear();
            MotherForm.Team = (TeamData)Team.Clone();
            this.Hide();
            IndexForm.GetInstance().Show();
        }

        #region "Open/Close Method"

        public void SaveTeam()
        {
            try
            {
                POHelper.WriteFile(Settings.Default.teamPath, Team);
                tempTeam = (TeamData)Team.Clone();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void OpenTeam(TeamData teamValue, bool constructing)
        {
            if (teamValue == null) return;
            Team = teamValue;
            tempTeam = (TeamData)teamValue.Clone();
            PokemonList.SelectedIndices.Clear();
            BindTeam(this.Team);
            ClearText();
        }

        private void NewTeam()
        {
            tempTeam = null;
            Team = new TeamData();

            CurrentInfo = PokemonCustomInfo.EmptyPokemon;
            Settings.Default.teamPath = "";
            BindTeam(this.Team);
            ClearText();
        }

        private bool CloseTeam()
        {
            if (Team.Pokemons[0].Identity == 0)
                return true;
            bool changed = !Team.Equals(tempTeam);
            if (changed)
            {
                DialogResult result = MessageBox.Show("是否保存改动?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
                switch (result)
                {
                    case DialogResult.Yes:
                        cmdSave.PerformClick();
                        break;
                    case DialogResult.Cancel:
                        return false;
                }
            }
            CurrentInfo = PokemonCustomInfo.EmptyPokemon;
            return true;
        }

        private void SetSelectedPokemon(PokemonCustomInfo newPM)
        {
            Team.Pokemons[PokemonList.SelectedIndices[0]] = newPM;
            if (PokemonList.SelectedIndices[0] == 0)
                return;
            for (int i = 0; i < PokemonList.SelectedIndices[0]; i++)
            {
                if (Team.Pokemons[i].Identity == 0)
                {
                    SwapPM(PokemonList.SelectedIndices[0], i);
                    return;
                }
            }
        }

        private void cmdSave_Click(object sender, EventArgs e)
        {
            string path = Settings.Default.teamPath;
            if (string.IsNullOrEmpty(path) || path.EndsWith(".ptd"))
            {
                cmdSaveTo.PerformClick();
            }
            else
            {
                SaveTeam();
            }
        }

        private void cmdSaveTo_Click(object sender, EventArgs e)
        {
            //var path = FileHelper.SaveFilePath("PBO File(*.ptd)|*.ptd;|PO File(*.tp)|*.tp;");
            var path = FileHelper.SaveFilePath("PO File(*.tp)|*.tp;");
            if (path.Length > 0)
            {
                Settings.Default.teamPath = path;
                SaveTeam();
                //if (Settings.Default.history.IndexOf(Settings.Default.teamPath) == -1)
                //    Settings.Default.history.Add(fileDialog.FileName);
            }
        }

        #endregion

        private void BindTeam(TeamData team)
        {
            if (team == null) return;
            PokemonList.Items.Clear();
            foreach (var pm in team.Pokemons)
            {
                if (pm.IsEmpty)
                {
                    PokemonList.Items.Add("无");
                }
                else
                {
                    if (!imgPM.Images.ContainsKey(pm.Identity.ToString()))
                    {
                        var data = GameService.GetPokemon(pm.Identity);
                        imgPM.Images.Add(data.Id.ToString(), GameService.GetImage(data.Id, data.Icon));
                    }
                    PokemonList.Items.Add(pm.NickName, pm.Identity.ToString());
                }
            }
        }

        #region "PokemonEdit"
        private void PokemonList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (PokemonList.SelectedIndices.Count == 0)
            {
                SwitchButton.Enabled = false;
                CurrentInfo = PokemonCustomInfo.EmptyPokemon;
                ClearText();
                return;
            }
            int index = PokemonList.SelectedIndices[0];
            if (object.ReferenceEquals(CurrentInfo, Team.Pokemons[index]))
                return;
            CurrentInfo = Team.Pokemons[index];
            if (!CurrentInfo.IsEmpty)
            {
                UpdatePM(CurrentInfo);
                cmdUp.Enabled = true;
                cmdDown.Enabled = true;
                ExpertButton.Enabled = true;
                LVNumberic.Enabled = true;
                NickNameText.Enabled = true;
                SwitchButton.Enabled = false;
            }
            else
            {
                ClearText();
            }
            PokemonCombo.Enabled = true;
        }

        private void ClearText()
        {
            PokemonCombo.SelectedIndex = 0;
            NickNameText.Clear();

            lblHPVal.Text = string.Empty;
            lblAtkVal.Text = string.Empty;
            lblDefVal.Text = string.Empty;
            lblSAtkVal.Text = string.Empty;
            lblSDefVal.Text = string.Empty;
            lblSpeedVal.Text = string.Empty;
            lblType1Name.Text = string.Empty;
            lblType2Name.Text = string.Empty;
            MoveList.Items.Clear();
            GetMoveText().ToList().ForEach(t => t.Clear());
            lblMoveInfo.Text = string.Empty;

            ItemCombo.SelectedIndex = 0;
            picPM.Image = null;
            ExpertButton.Enabled = false;
            ItemCombo.Enabled = false;
            LVNumberic.Enabled = false;
            cmdUp.Enabled = false;
            cmdDown.Enabled = false;
            SwitchButton.Enabled = true;
            PokemonCombo.Enabled = false;
            NickNameText.Enabled = false;
        }

        private void ExpertButton_Click(object sender, EventArgs e)
        {
            if (CurrentInfo != null)
            {
                var form = FrmExpertEditor.GetInstance(CurrentInfo);
                form.ShowDialog();
                UpdatePM(CurrentInfo, false);
            }
        }

        private void PokemonCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CurrentInfo.IsEmpty || updating) return;
            SwitchButton.Enabled = true;
        }

        private void nudLV_ValueChanged(object sender, EventArgs e)
        {
            if (CurrentInfo.IsEmpty) return;
            CurrentInfo.LV = Convert.ToByte(LVNumberic.Value);
            UpdatePM(CurrentInfo, false);
        }

        private void txtNickName_LostFocus(object sender, EventArgs e)
        {
            if (CurrentInfo.IsEmpty || PokemonList.SelectedItems.Count == 0)
                return;
            string name = NickNameText.Text.Trim();
            if (PBO.Data.Util.StringHelper.ValidatePmName(name))
            {
                CurrentInfo.NickName = name;
                PokemonList.SelectedItems[0].Text = CurrentInfo.NickName;
            }
            else
            {
                NickNameText.Text = CurrentInfo.NickName;
            }
        }

        private void SwapPM(int index1, int index2, bool ListSelect = true)
        {
            PokemonCustomInfo pm1 = Team.Pokemons[index1];
            PokemonCustomInfo pm2 = Team.Pokemons[index2];
            Team.Pokemons[index1] = pm2;
            Team.Pokemons[index2] = pm1;
            BindTeam(Team);
            if (!ListSelect)
                return;
            PokemonList.SelectedIndices.Add(index2);
            PokemonList.Focus();
        }

        private void ItemCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CurrentInfo.IsEmpty || updating)
                return;
            CurrentInfo.Item = (Item)ItemCombo.SelectedIndex;
        }

        private void cmdSearch_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(SearchText.Text))
            {
                ListViewItem item = MoveList.FindItemWithText(SearchText.Text);
                if (item != null)
                {
                    item.Selected = true;
                    MoveList.EnsureVisible(item.Index);
                    MoveList.Focus();
                }
            }
        }

        #endregion

        private void cmdUp_Click(object sender, EventArgs e)
        {
            if (PokemonList.SelectedIndices[0] == 0)
                return;
            SwapPM(PokemonList.SelectedIndices[0], PokemonList.SelectedIndices[0] - 1);
        }

        private void cmdDown_Click(object sender, EventArgs e)
        {
            if (PokemonList.SelectedIndices[0] == 5)
                return;
            if (Team.Pokemons[PokemonList.SelectedIndices[0] + 1].Identity == 0)
                return;
            SwapPM(PokemonList.SelectedIndices[0], PokemonList.SelectedIndices[0] + 1);
        }

        private void TeamEditorForm_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
            {
                if (MoveList.Items.Count == 0)
                    lblMoveInfo.Text = "";
                MotherForm.toolStripSeparator.Visible = true;
                MotherForm.保存SToolStripMenuItem.Visible = true;
                MotherForm.另存为AToolStripMenuItem.Visible = true;
                MotherForm.EditTeamMenuItem.Visible = false;
            }
            else
            {
                MotherForm.toolStripSeparator.Visible = false;
                MotherForm.保存SToolStripMenuItem.Visible = false;
                MotherForm.另存为AToolStripMenuItem.Visible = false;
                MotherForm.EditTeamMenuItem.Visible = true;
            }
        }

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SearchButton.PerformClick();
                e.SuppressKeyPress = true;
            }
        }

        private void SwitchButton_Click(object sender, EventArgs e)
        {
            int identity = Convert.ToInt32(PokemonCombo.SelectedValue);
            var data = GameService.GetPokemon(identity);
            //CurrentInfo = PBO.Data.Rnd.RandomData.GetSmogonPm(new Random(), identity);
            CurrentInfo = new PokemonCustomInfo();

            CurrentInfo.Identity = data.Id;
            CurrentInfo.NickName = data.NameBase;
            CurrentInfo.LV = 100;
            CurrentInfo.Gender = data.Genders.First();
            CurrentInfo.Nature = PokemonNature.Hardy;
            CurrentInfo.Ability = data.Traits.First();

            SetSelectedPokemon(CurrentInfo);

            for (int i = 0; i < 6; i++)
            {
                if (object.ReferenceEquals(Team.Pokemons[i], CurrentInfo))
                {
                    if (!imgPM.Images.ContainsKey(Convert.ToString(CurrentInfo.Identity)))
                    {
                        imgPM.Images.Add(CurrentInfo.Identity.ToString(), GameService.GetImage(data.Id, data.Icon));
                    }
                    PokemonList.Items[i].ImageKey = Convert.ToString(CurrentInfo.Identity);
                    PokemonList.Items[i].Text = CurrentInfo.NickName;
                }
            }

            SwitchButton.Enabled = false;
            ExpertButton.Enabled = true;
            LVNumberic.Enabled = true;

            if (CurrentInfo.LV != 100)
                return;

            UpdatePM(CurrentInfo);
            cmdUp.Enabled = true;
            cmdDown.Enabled = true;

            if (data.ItemRestriction == Item.None)
                ItemCombo.Enabled = true;
            NickNameText.Enabled = true;
        }

        #endregion

        #region file button

        private void cmdNew_Click(object sender, EventArgs e)
        {
            if (!CloseTeam()) return;
            NewTeam();
        }

        private void cmdOpen_Click(object sender, EventArgs e)
        {
            if (!CloseTeam()) return;
            string path = FileHelper.OpenFilePath("PBO or PO File(*.ptd,*.tp)|*.ptd;*.tp;");
            if (path.Length > 0) OpenTeam(FileHelper.LoadTeam(path), false);
        }

        #endregion

        #region pokemon

        private void UpdatePM(PokemonCustomInfo pm, bool updateMoveList = true)
        {
            updating = true;
            if (pm.IsEmpty) return;
            var data = GameService.GetPokemon(pm.Identity);

            PokemonCombo.SelectedValue = data.Id;
            NickNameText.Text = pm.NickName;
            LVNumberic.Value = pm.LV;

            var bs6d = CalculateHelper.GetBaseValue(pm.Nature, data.BaseStats, pm.Iv, pm.Ev, pm.LV);
            BindStats(bs6d);
            BindItem(pm, data);

            picPM.Image = GameService.GetImage(data.Id, data.FrontImage);

            lblType1Name.Text = data.Type1.ToCnName();
            lblType2Name.Text = data.Type2.ToCnName();

            if (updateMoveList)
            {
                lstUpdating = true;
                BindMoves(pm.Identity);
                BindMoveBox(pm.Moves);

                foreach (int mid in pm.Moves)
                {
                    CheckMove(mid);
                }

                lstUpdating = false;
            }
            updating = false;
        }

        private void BindItem(PokemonCustomInfo info, PokemonData data)
        {
            bool isRestriction = data.ItemRestriction != Item.None;
            ItemCombo.SelectedIndex = isRestriction ? (int)data.ItemRestriction : (int)info.Item;
            ItemCombo.Enabled = !isRestriction;
        }

        private void BindStats(IStats stats)
        {
            lblHPVal.Text = stats.Hp.ToString();
            lblAtkVal.Text = stats.Atk.ToString();
            lblDefVal.Text = stats.Def.ToString();
            lblSAtkVal.Text = stats.SpAtk.ToString();
            lblSDefVal.Text = stats.SpDef.ToString();
            lblSpeedVal.Text = stats.Speed.ToString();
        }

        #endregion

        #region move

        private void txtMoves_GotFocus(object sender, EventArgs e)
        {
            TextBox txt = (TextBox)sender;
            if (CurrentInfo.IsEmpty || string.IsNullOrEmpty(txt.Text))
            {
                return;
            }
            MoveList.FindItemWithText(txt.Text).Selected = true;
            MoveList.EnsureVisible(MoveList.SelectedIndices[0]);
            MoveList.Focus();
        }

        private void MoveList_SelectedIndexChanged(object sender, EventArgs e)
        {
            lblMoveInfo.Visible = true;
            lblMoveInfo.Enabled = true;
            if (MoveList.SelectedItems.Count > 0)
            {
                lblMoveInfo.Text = SQLiteHelper.MoveData.GetMoveInfo(Convert.ToInt32(MoveList.SelectedItems[0].Tag));
            }
            else
            {
                lblMoveInfo.Text = string.Empty;
            }
        }

        private void MoveList_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (MoveSorter != null) { MoveSorter.SetColumn(e.Column); MoveList.Sort(); }
        }

        private void MoveList_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (lstUpdating) return;
            int mid = Convert.ToInt32(e.Item.Tag);

            if (e.Item.Checked)
            {
                //if (CurrentInfo.Moves.Contains(mid)) return;
                if (CurrentInfo.Moves.All(i => i != 0))
                {
                    lstUpdating = true;
                    e.Item.Checked = false;
                    lstUpdating = false;
                    MessageBox.Show("技巧已满", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                string trait = PokemonValidator.CheckTrait(CurrentInfo.Identity, CurrentInfo.Ability, mid);
                if (trait.Length > 0)
                {
                    lstUpdating = true;
                    e.Item.Checked = false;
                    lstUpdating = false;
                    MessageBox.Show(e.Item.Text + "与特性无法共存", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                var moves = CurrentInfo.Moves.Where(m => m != 0).Union(new int[] { mid }).Distinct().ToArray();
                if (!PokemonValidator.CheckMoves(moves, GameService.GetPokemon(CurrentInfo.Identity)))
                {
                    lstUpdating = true;
                    e.Item.Checked = false;
                    lstUpdating = false;
                    //MessageBox.Show(_gameData.FalseMove1 + "与" + _gameData.FalseMove2 + "不可共存", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    MessageBox.Show("共存错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                CurrentInfo.AddMove(mid);
            }
            else
            {
                if (CurrentInfo.Moves.Count(i => i != 0) == 1)
                {
                    MessageBox.Show("至少要有一个技能！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    lstUpdating = true;
                    e.Item.Checked = true;
                    lstUpdating = false;
                    return;
                }
                CurrentInfo.RemoveMove(mid);
            }
            CurrentInfo.SortMoves();
            BindMoveBox(CurrentInfo.Moves);
        }

        private IEnumerable<TextBox> GetMoveText()
        {
            yield return MoveText1;
            yield return MoveText2;
            yield return MoveText3;
            yield return MoveText4;
        }

        private bool CheckMove(int mid)
        {
            if (mid == 0) return false;
            var name = GameService.GetMove(mid).Name;
            var item = MoveList.FindItemWithText(name);
            if (item != null) item.Checked = true;
            return item != null;
        }

        private void BindMoves(int pid)
        {
            MoveList.Items.Clear();
            var dt = DALDataDex.GetTeamMove(pid);
            foreach (DataRow dr in dt.Rows)
            {
                string[] arr = 
                {
                    dr["name"].ToString(),
                    dr["power"].ToString(),
                    dr["pp"].ToString(),
                    dr["accuracy"].ToString(),
                    dr["category"].ToString(),
                    dr["learntype"].ToString()
                };

                var item = new ListViewItem(arr, dr["movetype"].ToString().ToInt());
                item.Name = dr["name"].ToString();
                item.Tag = dr["moveid"].ToString();
                MoveList.Items.Add(item);
            }
        }

        private void BindMoveBox(int[] moves)
        {
            var list = GetMoveText().ToList();
            list.ForEach(t => t.Clear());
            for (int i = 0; i < moves.Length; i++)
            {
                list[i].Text = moves[i] == 0 ? string.Empty : GameService.GetMove(moves[i]).Name;
            }
        }

        #endregion

        private void cmdBox_Click(object sender, EventArgs e)
        {
            Clipboard.Clear();
            Clipboard.SetText(POHelper.ToString(this.Team));
        }

        #region poke bank test

        private static ITopClient client = new DefaultTopClient("http://219.148.7.14:800/api", "285332", "GwGfotAAvzry9TO1FHMsMDba0YArs9B0");
        
        private void RefreshBank(int page_no, int page_size)
        {
            var req = new Top.Api.Request.PokemonAllGetRequest();
            req.PageNo = page_no;
            req.PageSize = page_size;
            var rsp = client.Execute(req);
            BankPokemons = rsp.Pokemons;
            BindBank(BankPokemons);
        }

        private void RefreshBank()
        {
            var req = new Top.Api.Request.PokemonAllGetRequest();
            req.PageNo = (int)numericUpDown2.Value;
            req.PageSize = (int)numericUpDown1.Value;
            var rsp = client.Execute(req);
            numericUpDown2.Maximum = (decimal)Math.Ceiling((double)rsp.TotalResults / req.PageSize.Value);
            BankPokemons = rsp.Pokemons;
            BindBank(BankPokemons);
        }

        private List<Top.Api.Domain.Pokemon> BankPokemons;

        private void BindBank(List<Top.Api.Domain.Pokemon> pokemons)
        {
            listView1.Items.Clear();
            foreach (var pm in pokemons)
            {
                var info = GetInfo(pm);

                if (!imgPM.Images.ContainsKey(info.Identity.ToString()))
                {
                    var data = GameService.GetPokemon(info.Identity);
                    imgPM.Images.Add(data.Id.ToString(), GameService.GetImage(data.Id, data.Icon));
                }
                listView1.Items.Add(pm.Pid.ToString(), info.Identity.ToString());
            }
        }

        private static int InsertPo(PBO.Data.PokemonOnline.Pokemon po)
        {
            var req = new Top.Api.Request.PokemonAddRequest();
            req.Num = po.Num;
            req.Forme = po.Forme;
            req.Shiny = po.Shiny;
            req.Ability = po.Ability;
            req.Gen = po.Gen;
            req.Item = po.Item;
            req.Gender = po.Gender;
            req.SubGen = po.SubGen;
            req.Hapiness = po.Hapiness;
            req.Lvl = po.Lvl;
            req.Nature = po.Nature;

            req.Move1 = po.Move[0];
            req.Move2 = po.Move[1];
            req.Move3 = po.Move[2];
            req.Move4 = po.Move[3];

            req.DvHp = po.DV[0];
            req.DvAtk = po.DV[1];
            req.DvDef = po.DV[2];
            req.DvSpA = po.DV[3];
            req.DvSpD = po.DV[4];
            req.DvSpe = po.DV[5];

            req.EvHp = po.EV[0];
            req.EvAtk = po.EV[1];
            req.EvDef = po.EV[2];
            req.EvSpA = po.EV[3];
            req.EvSpD = po.EV[4];
            req.EvSpe = po.EV[5];

            var rsp = client.Execute(req);

            return rsp.Pid;
        }

        private static PBO.Data.PokemonOnline.Pokemon GetPo(Top.Api.Domain.Pokemon pm)
        {
            var po = new PBO.Data.PokemonOnline.Pokemon();
            po.Num = pm.Num;
            po.Forme = pm.Forme;
            po.Shiny = pm.Shiny;
            po.Ability = pm.Ability;
            po.Gen = pm.Gen;
            po.Item = pm.Item;
            po.Gender = pm.Gender;
            po.SubGen = pm.SubGen;
            po.Hapiness = pm.Hapiness;
            po.Lvl = pm.Lvl;
            po.Nature = pm.Nature;
            po.Move = new[] { pm.Move1, pm.Move2, pm.Move3, pm.Move4 };
            po.DV = new[] { pm.DvHp, pm.DvAtk, pm.DvDef, pm.DvSpA, pm.DvSpD, pm.DvSpe };
            po.EV = new[] { pm.EvHp, pm.EvAtk, pm.EvDef, pm.EvSpA, pm.EvSpD, pm.EvSpe };
            return po;
        }

        private static PokemonCustomInfo GetInfo(Top.Api.Domain.Pokemon pm)
        {
            return POHelper.ToInfo(GetPo(pm));
        }

        private void cmdIn_Click(object sender, EventArgs e)
        {
            if (PokemonList.SelectedItems.Count == 0) return;
            int index = PokemonList.SelectedIndices[0];
            var info = Team.Pokemons[index];
            var po = POHelper.ToPokemon(info);
            InsertPo(po);
            RefreshBank();
        }

        private void cmdOut_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0) return;
            int index = listView1.SelectedIndices[0];
            var pm = BankPokemons[index];
            var info = GetInfo(pm);
            info.NickName = info.Identity.ToString();
            Team.Pokemons[0] = info;
            BindTeam(Team);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshBank();
        }

        #endregion

        private void listView1_ItemMouseHover(object sender, ListViewItemMouseHoverEventArgs e)
        {
            int index = e.Item.Index;
            var pm = BankPokemons[index];
            var info = GetInfo(pm);
            e.Item.ToolTipText = POHelper.ToString(info);
        }
    }
}
